package calculator;
import java.math.BigDecimal;
import java.util.ArrayList;

/*
 * SymbolTable.java
 * Author: Ben McCormick
 * Written: Dec 27 2010
 * Last Edited: May 16 2011
 * Ben McCormick 2011
 * This file is part of The Eikona Project .
 *    Copyright 2011 Ben McCormick
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *    
 *    http://www.apache.org/licenses/LICENSE-2.0
 *    
 *     Unless required by applicable law or agreed to in writing, software
 *     distributed under the License is distributed on an "AS IS" BASIS,
 *     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *     See the License for the specific language governing permissions and
 *     limitations under the License.
 */


/**
 * Represents the symbol table for parsing arithmetic expressions
 * @author Ben McCormick
 *
 */
public class SymbolTable {
	private ArrayList[] sym;
	
	/**
	 * Creates the symbol table
	 */
	public SymbolTable() {
		
		sym=new ArrayList[3];   //Symbol Table
		sym[0]=new ArrayList<String>();
		 sym[1]=new ArrayList<String>();
		 sym[2]=new ArrayList<BigDecimal>();
	}
	
	/**
	 * Adds a new entry to the symbol table
	 * @param type
	 * @param name
	 * @param val
	 */
	public void add(String type, String name, BigDecimal val)
	{
		sym[0].add(type);
		sym[1].add(name);
		try{
		if( val == null || val.compareTo(new BigDecimal(-1)) == 0)
		{
			sym[2].add(null);
		}
		else
		sym[2].add(val);
		}
		catch(NumberFormatException e)
		{
			sym[2].add(null);
		}
	}
	
	/**
	 * Tests if the symbol table already contains a specific token
	 * @param a
	 * @return
	 */
	public boolean contains(String a)
	{
		return (sym[1].contains(a));
	}
	/**
	 * Gives the number of entries in the Symbol table
	 * @return
	 */
	public int size()
	{
		return (sym[0].size());
	}
	
	/**
	 * Returns the type of the token at index x
	 * @return
	 */
	public String getType(int x)
	{
		return (String) sym[0].get(x);
	}
	/**
	 * Returns the name of the token at index x
	 * @param x
	 * @return
	 */
	public String getName(int x)
	{
		return (String) sym[1].get(x);
	}
	/**
	 * returns the value of the token at index x
	 * @param x
	 * @return
	 */
	public BigDecimal getValue(int x)
	{
		return (BigDecimal) (sym[2].get(x));
	}
	/**
	 * Sets the value of a symbol table entry
	 * @param ref
	 * @param value
	 */
	public void setValue(int ref, BigDecimal value)
	{
	sym[2].set(ref, value);	
	}
	
	/**
	 * Returns the double value associated with a particular variable name
	 * @param var
	 * @return
	 */
	public Number getVarValue(String var)
	{
	for(int i=0; i<size(); i++)
	{
		if(getName(i).equals(var))
		{
			return getValue(i);
		}
	}
	return new BigDecimal(-1);
	}
	
	/**
	 * Sets the value of variable var to val
	 * @param var
	 * @return
	 */
	public void setVarValue(String var, Number val)
	{
	for(int i=0; i<size(); i++)
	{
		if(getName(i).equals(var))
		{
			sym[2].set(i, val);	
		}
	}
	}
	
}
